# 导包
import tornado.web

# 服务器
from tornado import httpserver

# 导入基础类
from base import BaseHandler

# 导入数据库操作类
from db import database,User,myser

# 异步执行库
import peewee_async

# 导入用户视图
from user_view import UserInfo,UserRole,Upload,AuditUpdate,Ocview,WsHandler,Push,ChatList,ClientHandler,OutServer

from playhouse.shortcuts import model_to_dict

from tools import send_mail

import json

import os

# 设置tornado静态文件夹目录
static_path = os.path.join(os.path.dirname(__file__),"static")


from peewee import fn


import tornado.websocket as websocket


#导入支付基类
from pay import AliPay

import time

#初始化阿里支付对象
def get_ali_object():
    # 沙箱环境地址：https://openhome.alipay.com/platform/appDaily.htm?tab=info
    app_id = "2016092600603658"  #  APPID （沙箱应用）

    # 支付完成后，支付偷偷向这里地址发送一个post请求，识别公网IP,如果是 192.168.20.13局域网IP ,支付宝找不到，def page2() 接收不到这个请求
    notify_url = "https://localhost/alipayreturn/"

    # 支付完成后，跳转的地址。
    return_url = "https://localhost/alipayreturn/"

    merchant_private_key_path = "./keys/app_private_2048.txt" # 应用私钥
    alipay_public_key_path = "./keys/alipay_public_2048.txt"  # 支付宝公钥

    alipay = AliPay(
        appid=app_id,
        app_notify_url=notify_url,
        return_url=return_url,
        app_private_key_path=merchant_private_key_path,
        alipay_public_key_path=alipay_public_key_path,  # 支付宝的公钥，验证支付宝回传消息使用，不是你自己的公钥
        debug=True,  # 默认False,
    )
    return alipay

class PayTest(BaseHandler):

	async def get(self):

		alipay = get_ali_object()

		money = 10
		query_params = alipay.direct_pay(
			subject="test",
			out_trade_no="myorder" + str(time.time()),
			total_amount=money,)
		pay_url = "https://openapi.alipaydev.com/gateway.do?{0}".format(query_params)
		return self.redirect(pay_url)


class ProStatus:

    connector = {}  # 记录当前连接的user

    def user_connect(self, user):
    	print(user)
    	if user not in self.connector:
    		self.connector[user] = "user"

    def user_remove(self, user):
        self.connector.remove(user)

    def trigger(self, message):
        ''' 向所有被记录的客户端推送最新内容 '''
        for user in self.connector:
            #user.write_message(message)
            try:
            	user.write_message(message)
            except websocket.WebSocketClosedError as err:
            	print(str(err))
            	pass


class WsBaseHandler(tornado.websocket.WebSocketHandler):
    def check_origin(self, origin):
        '''重写同源检查 解决跨域问题'''
        return True

    def open(self):
        '''新的websocket连接后被调动'''
        self.write_message('Welcome')

    def on_close(self):
        '''websocket连接关闭后被调用'''

    def on_message(self, message):
        '''接收到客户端消息时被调用'''
        self.write_message('new message :' + message)  # 向客服端发送

# class WsHandler(WsBaseHandler):

# 	def open(self):
		
# 		self.write_message('你好')
# 		ProStatus().user_connect(self) #用户连接后记录

# 	def on_close(self):
# 		ProStatus().user_remove(self)  # 断开连接后remove

# 	def on_message(self,message):

# 		self.write_message('new message :' + message)


from peewee_async import Manager

# 类视图
class TestHandler(BaseHandler):

	# 声明异步
	async def get(self):

		#print(set())

		#print(ProStatus().connector)

		#ProStatus().trigger("你好你好")

		try:
	
			async with self.application.objects.atomic():
				


				user = await self.application.objects.get(User,id=1)
				user.state = 1

				await self.application.objects.update(user)

				insert = {"username":"123123","type":2,"password":"123123"}
				await self.application.objects.create(User,**insert)

		except Exception as e:

			print(e)




		# 接收参数
		num = self.get_argument("num",10)

		# 获取余额
		# users = await self.application.objects.execute(Comment.select(Comment.sid,fn.COUNT(Comment.id).alias('ct')).group_by(Comment.sid))

		#await send_mail("123","123","123","123")

		# 异步获取多个
		#users = await self.application.objects.get(User.select().get())
		#print(users)
		#users = myser(users,many=True)
		# users = [myser(x) for x in users]
		# print(users)
		# users = User.select()

		# for x in users:
		# 	print(x.ct,x.sid)
		

		#print(user.num)

		# 添加数据
		#user = await self.application.objects.create(User,username="异步数据",age=20)

		# 修改数据
		#user.num = 500
		#await self.application.objects.update(user)

		# 异步删除
		#await self.application.objects.delete(user)

		#res = User.create(username="测试账号",age=20,phone="123321231")

		# 修改余额
		#user.num = user.num + int(num)
		#user.save()
		#await self.application.objects.update(user)

		#data = json.loads(json.dumps(model_to_dict(user),default=str))

		#print(data)

		return self.write({'code':200,'msg':'123'})

	# async def post(self):

	# 	# 接收参数
	# 	id = self.get_argument("id",None)

	# 	print(id)

	# 	return self.write({'code':200,'msg':'hello world','id':id})


# 执行tornado
# 执行方法
def main():
	# 实例化tornado对象
	app = tornado.web.Application(

		handlers=[

			# 首页
			(r'/',TestHandler),
			(r'/ws/',WsHandler),
			(r'/paytest/',PayTest),

			# 用户模块
			(r'/user/',UserInfo),
			(r'/role/',UserRole),
			(r'/upload/',Upload),
			(r'/auditupdate/',AuditUpdate),
			(r'/oc/',Ocview),
			(r'/push/',Push),
			(r'/chatlist/',ChatList),
			(r'/client/',ClientHandler),
			(r'/outserver/',OutServer),


		],static_path=static_path,debug=True
	)
	# 将异步数据库操作，注入tornado
	app.objects = peewee_async.Manager(database)
	# 声明服务器
	server = httpserver.HTTPServer(app,xheaders=True,ssl_options={
		# 证书文件
		"certfile":"./localhost.crt",
		# 密钥文件
		"keyfile":"./localhost.key"

	})
	# 指定端口
	server.listen(443)
	#server.listen(443)
	# 执行事件循环 ioloop
	tornado.ioloop.IOLoop.instance().start()

if __name__ == '__main__':
	print("服务已经启动!")
	main()